home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / ms_dos / happysrc / paasm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-08  |  26.2 KB  |  774 lines

  1. /**********************************************************************
  2.  *
  3.  *       *** HAPPy Pascal Compiler ***
  4.  *               P-code assmebler
  5.  *
  6.  *           Copyright (c) H.Asano 1992.
  7.  *
  8.  **********************************************************************/
  9.  
  10. #define EXTERN extern
  11. #define Maxlabel   1800                 /* 最大ラベル数               */
  12.  
  13. #include <float.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. #include "version.h"
  18. #include "hapai.h"
  19.  
  20. /********* co-operation table **********/
  21. static unsigned char cop[] = 
  22.   {
  23.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9   */
  24.    /* 0x */    115,  105,   70,   75,    0,    0,   80,    0,    0,   85,
  25.    /* 1x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  26.    /* 2x */      0,    0,    0,    0,    0,    0,   95,    0,    0,    0,
  27.    /* 3x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  28.    /* 4x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  29.    /* 5x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  30.    /* 6x */      0,    0,    0,    0,    0,    0,    0,    0,    0,    0
  31.   } ;
  32.  
  33.  
  34. /***************************************/
  35. /* P-code 標準手続き・関数ニーモニック表*/
  36. /***************************************/
  37. static char sptable[][4] =
  38. {
  39.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9  */
  40.    /* 0x */  "get","put","rst","rln","new","wln","wrs","wrb","wri","wrr",
  41.    /* 1x */  "wrc","rdi","rdr","rdc","sin","cos","exp","log","sqt","atn",
  42.    /* 2x */  "pge","eof","eol","dis","wrf","rwt","trs","trw","tgt","tpt"
  43. } ;
  44.  
  45. /***************************************/
  46. /*            ラベル表                 */
  47. /***************************************/
  48. enum lbst {  entered,                   /* ラベル未登録の状態         */
  49.              defined                    /* ラベル定義済の状態         */
  50.           };
  51.  
  52. static struct  {
  53.   int val               ;               /* value                      */
  54.   enum lbst st          ;               /* status {enterd,defined}    */
  55. } labeltab[Maxlabel]    ;
  56.  
  57. /***************************************/
  58. /*      仮想計算機 記憶装置            */
  59. /***************************************/
  60. static _store store[Maxstore] ;
  61.  
  62. /***************************************/
  63. /*            変数定義                 */
  64. /***************************************/
  65. static char *PcodeSourceName;           /* P-codeソースファイル名      */
  66. static char *CompVersion    ;           /* コンパイラのバージョン     */
  67. static FILE *pcsfile        ;           /* P-codeソースファイルポインタ         */
  68. static FILE *objfile        ;           /* P-codeオブジェクトファイルポインタ    */
  69. static int  codesize        ;           /* コードのワードサイズ           */
  70. static int  objsize         ;           /* オブジェクト全体のワードサイズ */
  71. static int  labelvalue      ;           /* labelの値                  */
  72. static char ch              ;           /* 読込文字                   */
  73. static int  intch           ;           /* 読込処理内での読込文字     */
  74. static int            pc    ;           /* program counter            */
  75. static unsigned char  op    ;           /* P-code operation           */
  76. static unsigned char  p     ;           /* P-code p operand           */
  77. static int            q     ;           /* P-code q operand           */
  78. static int start = -1       ;           /* オブジェクト開始の合図     */
  79.  
  80. /*********************************************************************/
  81.  
  82. /***************************************/
  83. /*     エラーメッセージ出力処理        */
  84. /***************************************/
  85. static void paerr(int errno)
  86. {
  87.   static struct _errmsg {
  88.        int  msgno       ;               /* error message number       */
  89.        char *errmsg     ;               /* error message              */
  90.      } errtb[]  =  {
  91.  
  92.    {1,  "命令数が多すぎてアセンブルできない"},
  93.    {2,  "オブジェクトファイルがオープンできない"},
  94.    {3,  "オブジェクトファイル書き込みでエラーが発生した"},
  95.    {4,  "ラベル数が多すぎてアセンブルできない"},
  96.    {5,  "定数を格納するメモリを使い果たしてアセンブルできない"},
  97.    {6,  "P-codeソースファイルがオープンできない"},
  98.    {7,  "PC.EXEとPA.OVLのバージョンが違う"}
  99. } ;
  100.   int i = -1 ;
  101.  
  102.      while(errtb[++i].msgno != errno) ; /* search message             */
  103.      fprintf(stderr,"A%03d: %s\n", errno, errtb[i].errmsg);
  104.      exit(3) ;                          /* アセンブルエラーで停止     */
  105. }
  106.  
  107. /***************************************/
  108. /*      reset() : reset関数            */
  109. /***************************************/
  110. static void reset(char *filename)
  111. {
  112.  
  113.      pcsfile = fopen(filename,"r") ;
  114.      if(pcsfile == NULL) paerr(6) ;
  115.  
  116.      intch =  getc(pcsfile)  ;          /* 1文字先読み                */
  117. }
  118.  
  119. /***************************************/
  120. /*       eoln() : eolnマクロ定義       */
  121. /***************************************/
  122. #define eoln()   (intch == '\n')        /* 改行を読んでいれば真       */
  123.  
  124. /***************************************/
  125. /* readc() : char型read処理            */
  126. /***************************************/
  127. static char readc(void)
  128. {
  129.   int oldch ;
  130.  
  131.      oldch    = intch     ;
  132.      intch    = getc(pcsfile) ;
  133.      return((char)oldch)  ;
  134. }
  135.  
  136. /***************************************/
  137. /*   readi() : integer型入力処理       */
  138. /***************************************/
  139. static integer readi(void)
  140. {
  141.   integer  ival = 0 ;
  142.   int      sign = 1 ;
  143.  
  144.      if(intch == ' ')
  145.       while((intch = getc(pcsfile)) == ' '); /* 空白読み飛ばし        */
  146.  
  147.      if((intch=='+') || (intch=='-')) {  /* 符号の時                  */
  148.       sign = (intch=='+') ? 1 : -1  ;    /* 符号に応じた正負          */
  149.       intch  = getc(pcsfile) ;
  150.      }
  151.  
  152.      do {
  153.       intch -= '0' ;
  154.       ival = ival*10 + intch ;
  155.       if(eoln()) break ;                /* EOLNならばそこまで         */
  156.       intch=getc(pcsfile) ;
  157.      } while(('0' <= intch) && (intch <= '9')) ;
  158.  
  159.      return(sign*ival) ;
  160. }
  161.  
  162. /***************************************/
  163. /*   readr() : real型入力処理          */
  164. /***************************************/
  165. static float readr(void)
  166. {
  167.   char buf[20] ;
  168.   int  i = 0   ;
  169.   
  170.      while(intch == ' ') intch = getc(pcsfile) ;   /* 空白読み飛ばし */
  171.      do {
  172.       buf[i++] = (char)intch ;
  173.       intch = getc(pcsfile) ;
  174.      } while (intch != '\n') ;
  175.  
  176.      return((float)atof(buf)) ;         /* 浮動小数点へ変換           */
  177. }
  178.  
  179. /***************************************/
  180. /* readln() : EOLまで読み飛ばす処理    */
  181. /***************************************/
  182. static void readln(void)
  183. {
  184.      while(!eoln()) intch = getc(pcsfile) ;
  185.      intch = getc(pcsfile);
  186. }
  187.  
  188. /***************************************/
  189. /*    オブジェクトファイル書出処理     */
  190. /***************************************/
  191. static void putobject(char *area, int size)
  192. {
  193.       fwrite(area,size,1,objfile) ;
  194.       if(ferror(objfile)) paerr(3) ;    /* 書き込み失敗               */
  195. }
  196.  
  197. /***************************************/
  198. /*          初期設定処理               */
  199. /***************************************/
  200. static void init(void)
  201. {
  202.   int i;
  203.  
  204.      _fpreset() ;                      /* 浮動小数点パッケージ初期設定*/
  205.      for(i=0;i<Maxlabel;i++) {          /* ラベル表 の 初期設定       */
  206.       labeltab[i].val = -1 ;    
  207.       labeltab[i].st  = entered;
  208.      }
  209.  
  210.      reset(PcodeSourceName) ;           /* P-codeソースファイルのオープン       */
  211.  
  212.      objfile = fopen("pcode.pco","wb") ;/* ファイルオープン           */
  213.      if(objfile == NULL) paerr(2) ;     /* オープンできない           */
  214.  
  215.      if(codesize > Maxstore)           /* 記憶装置の大きさより大きい時*/
  216.       paerr(1) ;                        /* プログラム停止                */
  217.  
  218.      if(strcmp(CompVersion,version))
  219.       paerr(7) ;                        /* バージョン不一致           */
  220.  
  221.      putobject(version,strlen(version)+1) ; /* バージョン番号書出     */
  222.  
  223.      objsize = codesize ;
  224. }
  225.  
  226. /***************************************/
  227. /*    ラベル表登録処理                 */
  228. /***************************************/
  229. static void update(int x)
  230. {                                       /*  x: label名                */
  231.    int curr,succ ;
  232.    
  233.      if(x > Maxlabel-1) paerr(4) ;      /* ラベル数が多すぎる         */
  234.       
  235.      if(labeltab[x].val != -1) {        /* 前方参照されている時       */
  236.       curr = labeltab[x].val;
  237.       for(;;) {
  238.        succ = store[curr].vo.cdq;
  239.        store[curr].vo.cdq = labelvalue;
  240.        if(succ == -1)  break;           /* 終了                       */
  241.        else            curr = succ;
  242.       }
  243.      }
  244.      labeltab[x].st  = defined    ;
  245.      labeltab[x].val = labelvalue ;
  246. }
  247.  
  248. /***************************************/
  249. /*     ラベル値決定処理                */
  250. /***************************************/
  251. static void lookup(int x)
  252. {
  253.      if(labeltab[x].st == entered) {    /* 未定義                     */
  254.       q = labeltab[x].val     ;         /* 初期値のまま -1           */
  255.       labeltab[x].val = pc    ;         /* 今のpcを格納               */
  256.      }
  257.      else q = labeltab[x].val ;         /* 定義済の時                 */
  258. }
  259.  
  260. /***************************************/
  261. /*     ラベル値読込処理                */
  262. /***************************************/
  263. static void labelsearch(void)
  264. {
  265.      while(ch != 'L')                   /* 'L' まで 読み飛ばし        */
  266.       ch = readc() ;
  267.      lookup((int)readi());              /* labelを読み 値を探す       */
  268. }
  269.  
  270.  
  271. /********* typesymbol() : instruction名4文字目によってopを決定する *********/
  272. static void typesymbol(void) 
  273. {
  274.    int i;
  275.  
  276.      switch(ch) {
  277.       case 'i' : return ;       /* 'i' の時は opはそのまま */
  278.       case 'a' : i=0; break;
  279.       case 'r' : i=1; break;
  280.       case 's' : i=2; break;
  281.       case 'b' : i=3; break;
  282.       case 'c' : i=4;
  283.      }
  284.      op=cop[op]+i;             /* opの変更 */
  285. }
  286.  
  287. /**************************************/
  288. /* PTN0() : オペランドのない命令      */
  289. /**************************************/
  290. static void PTN0(void)
  291. {
  292. }
  293.  
  294. /**************************************/
  295. /* PTN1() : lod,strのアセンブル       */
  296. /**************************************/
  297. static void PTN1(void)
  298. {
  299.      typesymbol() ;
  300.      p=(unsigned char)readi() ;
  301.      q=(int)readi() ;
  302. }
  303.  
  304. /**************************************/
  305. /* PTN2() : lda,movのアセンブル       */
  306. /**************************************/
  307. static void PTN2(void)
  308. {
  309.      p=(unsigned char)readi() ;
  310.      q=(int)readi() ;
  311. }
  312.  
  313. /***************************************/
  314. /* PTN3() : mst,cui,bas,traのアセンブル*/
  315. /***************************************/
  316. static void PTN3(void)
  317. {
  318.      p=(unsigned char)readi() ;
  319. }
  320.  
  321. /**************************************/
  322. /* PTN4() : cup,ent,ejpのアセンブル   */
  323. /**************************************/
  324. static void PTN4(void)
  325. {
  326.      p=(unsigned char)readi() ;
  327.      labelsearch();
  328. }
  329.  
  330. /************************************************/
  331. /* PTN5() : equ,neq,geq,grt,leq,lesのアセンブル */
  332. /************************************************/
  333. static void PTN5(void)
  334. {
  335.      switch(ch) {
  336.       case 'a' :     ; break ;
  337.       case 'i' : p=1 ; break ;
  338.       case 'r' : p=2 ; break ;
  339.       case 'b' : p=3 ; break ;
  340.       case 's' : p=4 ; break ;
  341.       case 'c' : p=6 ; break ;
  342.       case 'm' : p=5 ;
  343.       q=(int)readi() ;
  344.      }
  345. }
  346.  
  347. /**************************************/
  348. /* PTN6() : ldo,sroのアセンブル       */
  349. /**************************************/
  350. static void PTN6(void)
  351. {
  352.      typesymbol() ;
  353.      q=(int)readi();
  354. }
  355.  
  356. /**************************************/
  357. /* PTN7() : inc,decのアセンブル       */
  358. /**************************************/
  359. static void PTN7(void)
  360. {
  361.      switch(ch) {
  362.       case 'a' :/*p=0*;*/ break ;
  363.       case 'i' :  p=1;    break ;
  364.       case 'r' :  p=2;    break ;
  365.       case 'b' :  p=3;    break ;
  366.       case 'c' :  p=6;    break ;
  367.      }
  368.      q = (int)readi() ;
  369. }
  370.  
  371. /****************************************/
  372. /* PTN8() : ujp,fjp,xjp,lapのアセンブル */
  373. /****************************************/
  374. static void PTN8(void)
  375. {
  376.      labelsearch() ;
  377. }
  378.  
  379. /**************************************/
  380. /* CHK() : chkのアセンブル            */
  381. /**************************************/
  382. static void CHK(void)
  383. {
  384.    integer  lb,ub ;
  385.  
  386.      typesymbol() ;
  387.      p = (unsigned char)readi() ;       /* チェック種別              */
  388.      lb = readi();                      /* 下限値                     */
  389.      ub = readi();                      /* 上限値                     */
  390.      store[objsize  ].vi = lb ;
  391.      store[objsize+1].vi = ub ;
  392.      q=codesize;
  393.      do {
  394.       q++ ;
  395.      } while((store[q-1].vi != lb) || (store[q].vi != ub)) ;
  396.     if(q-1 == objsize) {
  397.      objsize += 2 ;
  398.      if(objsize>=Maxstore) paerr(5) ;   /* 定数格納不可               */
  399.     }
  400. }
  401.  
  402. /**************************************/
  403. /* CSP() : cspのアセンブル            */
  404. /**************************************/
  405. static void CSP(void)
  406. {
  407.    char name[4];
  408.  
  409.      do ;
  410.      while((ch=readc())==' ') ;         /* 空白を読み飛ばし           */
  411.      *name     = ch       ;             /* 1文字目                    */
  412.      *(name+1) = readc()  ;             /* 2文字目                    */
  413.      *(name+2) = readc()  ;             /* 3文字目                    */
  414.      *(name+3) = '\0'     ;
  415.      while(strcmp(sptable[q],name) != 0)/*対応のqをサーチ             */
  416.       q++ ;
  417. }
  418.  
  419. /**************************************/
  420. /* IND() : indのアセンブル            */
  421. /**************************************/
  422. static void IND(void)
  423. {
  424.      typesymbol() ;
  425.      q=(int)readi() ;
  426. }
  427.  
  428. /**************************************/
  429. /* IXA() : ixaのアセンブル            */
  430. /**************************************/
  431. static void IXA(void)
  432. {
  433.   integer lb,ub ;
  434.  
  435.      lb = readi() ;                     /* 下限値                     */
  436.      ub = readi() ;                     /* ixa値                      */
  437.      store[objsize  ].vi = lb ;
  438.      store[objsize+1].vi = ub ;
  439.      q=codesize;
  440.      do {
  441.       q++ ;
  442.      } while((store[q-1].vi != lb) || (store[q].vi != ub)) ;
  443.      if(q-1 == objsize) {
  444.       objsize += 2 ;
  445.       if(objsize>=Maxstore) paerr(5) ;  /* 定数域格納不可             */
  446.      }
  447. }
  448.  
  449. /**************************************/
  450. /* LAO() : laoのアセンブル            */
  451. /**************************************/
  452. static void LAO(void)
  453. {
  454.      q=(int)readi();
  455. }
  456.  
  457. /**************************************/
  458. /* LCA() : lcaのアセンブル            */
  459. /**************************************/
  460. static void LCA(void)
  461. {
  462.      q=objsize;
  463.      readc() ;                          /* "を読み飛ばす              */
  464.      ch=readc() ;                       /* "の次の文字                */
  465.      while(ch != '\"') {
  466.       store[objsize++].vc = ch ;
  467.       if(objsize>=Maxstore) 
  468.        paerr(5) ;                       /* 定数格納不可               */
  469.       ch=readc() ;                      /* 次の文字                   */
  470.      } 
  471. }
  472.  
  473. /**************************************/
  474. /* LDC() : ldcのアセンブル            */
  475. /**************************************/
  476. static void LDC(void)
  477. {
  478.   integer lnumber ;
  479.   float   rnumber ;
  480.   long    s,s1    ;
  481.  
  482.      switch(ch) {
  483.       case 'i' : p=1 ;                  /* integer type               */
  484.                  lnumber = readi() ;
  485.                  if(labs(lnumber) < (long)Largeint)
  486.                   q = (int)lnumber;
  487.                  else {                 /* 大きな数の時               */
  488.                   op = 66 ;             /* lci命令に変更              */
  489.                   store[objsize].vi = lnumber ;
  490.                   q=codesize-1;
  491.                   do ;
  492.                   while(store[++q].vi != lnumber) ;
  493.                   if(q == objsize) {
  494.                    objsize++  ;
  495.                    if(objsize>=Maxstore)
  496.                     paerr(5) ;          /* 定数格納不可               */
  497.                   }
  498.                  }
  499.                  break ;
  500.  
  501.       case 'c' : p=6 ;                  /* char type                  */
  502.                  while((ch=readc())==' ') ; 
  503.                  q=readc() ;
  504.                  break ;
  505.  
  506.       case 'b' : p=3;                   /* boolean                    */
  507.                  q=(int)readi() ;
  508.                  break;
  509.  
  510.       case 'n' : p=0 ;                  /* ldc nil                    */
  511.                  q=0 ; 
  512.                  break ;
  513.  
  514.       case 's' : p  = 4;                /* set type                   */
  515.                  s=0;
  516.                  while(readc() != '(') ;
  517.                  ch=readc() ;
  518.                  while(ch!=')') {
  519.                   s1=(int)readi() ;
  520.                   addset(s,s1)  ;
  521.                   ch=readc()   ;
  522.                  }
  523.                  store[objsize].vs = s ;
  524.                  q = codesize ;
  525.                  while(store[q].vs != s) q++ ;
  526.                  if(q==objsize) {
  527.                   objsize++ ;
  528.                   if(objsize>=Maxstore)
  529.                    paerr(5) ;           /* 定数格納不可               */
  530.                  }
  531.                  break ;
  532.  
  533.       case 'r' : p = 2 ;
  534.                  rnumber = readr() ;
  535.                  store[objsize].vr = rnumber ;
  536.                  lnumber = store[objsize].vi ;
  537.                  /* 浮動小数点の形で比較を行うと思わぬ落とし穴があるので
  538.                    ビット列の比較をするために、union型のviから数を得る*/
  539.                  q=codesize-1;
  540.                  do ;
  541.                  while(store[++q].vi != lnumber) ;
  542.                  if(q == objsize) {
  543.                   objsize++  ;
  544.                   if(objsize>=Maxstore)
  545.                    paerr(5) ;           /* 定数格納不可               */
  546.                  }
  547.                  break ;
  548.      }
  549. }
  550.  
  551. /**************************************/
  552. /* ORD() : ordのアセンブル            */
  553. /**************************************/
  554. static void ORD(void)
  555. {
  556.      switch(ch) {
  557.       case 'b' : p=3 ; break ;
  558.       case 'c' : p=6 ;
  559.      } 
  560. }
  561.  
  562. /**************************************/
  563. /* RET() : retのアセンブル            */
  564. /**************************************/
  565. static void RET(void)
  566. {
  567.      switch(ch) {
  568.       case 'p' :     ; break ;
  569.       case 'i' : p=1 ; break ;
  570.       case 'r' : p=2 ; break ;
  571.       case 'c' : p=3 ; break ;
  572.       case 'b' : p=4 ; break ;
  573.       case 'a' : p=5 ; break ;
  574.      }
  575. }
  576.  
  577. /**************************************/
  578. /* STO() : stoのアセンブル            */
  579. /**************************************/
  580. static void STO(void)
  581. {
  582.      typesymbol() ;
  583. }
  584.  
  585. /**********************************************************************/
  586. /*                   P-code ニーモニック表                            */
  587. /**********************************************************************/
  588. static char instr[][4] = 
  589. {
  590.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9  */
  591.    /* 0x */  "lod","ldo","str","sro","lda","lao","sto","ldc","bas","ind",
  592.    /* 1x */  "inc","mst","cup","ent","ret","csp","ixa","equ","neq","geq",
  593.    /* 2x */  "grt","leq","les","ujp","fjp","xjp","chk","lap","adi","adr",
  594.    /* 3x */  "sbi","sbr","sgs","flt","flo","trc","ngi","ngr","sqi","sqr",
  595.    /* 4x */  "abi","abr","not","and","ior","dif","int","uni","inn","mod",
  596.    /* 5x */  "odd","mpi","mpr","dvi","dvr","mov","lca","dec","stp","ord",
  597.    /* 6x */  "chr","ujc","mms","msi","cui","ejp","...","cka","tra","rou"
  598. } ;                                         /*    ↑ ここはlci */
  599.  
  600. /******* ニーモニック対応のエントリ表 ********/
  601. static struct entry { 
  602.        void (*func)(void) ;
  603. } OP[] = {
  604.    /*          x0    x1    x2    x3    x4    x5    x6    x7    x8    x9  */
  605.    /* 0x */   PTN1, PTN6 ,PTN2, PTN6, PTN2, LAO , STO , LDC , PTN3, IND ,
  606.    /* 1x */   PTN7, PTN3, PTN4, PTN4, RET , CSP , IXA , PTN5, PTN5, PTN5,
  607.    /* 2x */   PTN5, PTN5, PTN5, PTN8, PTN8, PTN8, CHK , PTN8, PTN0, PTN0,
  608.    /* 3x */   PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0,
  609.    /* 4x */   PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0, PTN0,
  610.    /* 5x */   PTN0, PTN0, PTN0, PTN0, PTN0, PTN2, LCA , PTN7, PTN0, ORD ,
  611.    /* 6x */   PTN0, PTN0, PTN0, PTN0, PTN3, PTN4, PTN0, PTN0, PTN3, PTN0
  612. } ;
  613.  
  614. /***************************************/
  615. /*     1行アセンブル処理               */
  616. /***************************************/
  617. static void assemble(void)
  618. {
  619.    char name[4];
  620.  
  621.      *name     = ch       ;            /* 1文字目 */
  622.      *(name+1) = readc()  ;            /* 2文字目 */
  623.      *(name+2) = readc()  ;            /* 3文字目 */
  624.      *(name+3) = '\0'     ;
  625.      if(!eoln()) ch=readc();
  626.       /* そこで行が終わってなければ次の文字を読む */
  627.  
  628.      op = -1 ;
  629.      while(strcmp(instr[++op],name)) ;  /* instructionよりopを決定    */
  630.          /* このようなリニアサーチはスピードが遅いので改良しよう      */
  631.  
  632.      p   =  0 ;
  633.      q   =  0 ;
  634.      OP[op].func() ;                    /* opに対応したアセンブル     */
  635.  
  636.      store[pc  ].vo.cdop = op;          /* code table へ 格納        */
  637.      store[pc  ].vo.cdp  = p ;
  638.      store[pc++].vo.cdq  = q ;
  639. }
  640.  
  641. /********** generate() :  行の最初に呼ばれる処理 **********/
  642. static void generate(void)
  643. {
  644.    int x     ;                          /* label値                    */
  645.    int i     ;                          /* 作業カウンタ               */
  646.    char progname[33] ;                  /* プログラム名               */
  647.    char filename[33] ;                  /* ファイル名                 */
  648.    int fileadr       ;                  /* ファイルアトレス           */
  649.    int filesize      ;                  /* バッファ変数の大きさ       */
  650.  
  651.      for(;;) {
  652.       ch=readc();                       /* 行の最初の文字を読む       */
  653.       switch(ch) {
  654.        case 'Q' : return ;              /* アセンブル終わり           */
  655.  
  656.        case 'N' :                       /* プログラム名               */
  657.                   readc() ;             /* 空白を読み飛ばす           */
  658.                   i=0 ;
  659.                   while(!eoln())        /* プログラム名取得           */
  660.                    progname[i++] = readc() ;
  661.                   progname[i] = '\0' ;
  662.                   putobject(progname,i+1) ; /* 書出                   */
  663.                   break ;
  664.  
  665.        case 'F' :                       /* ファイルアドレス           */
  666.                   readc() ;             /* 空白を読み飛ばす           */
  667.                   i=0 ;
  668.                   while((ch=readc()) != ' ') /* ファイル名取得        */
  669.                    filename[i++] = ch ;
  670.                   filename[i] = '\0'  ; 
  671.                   readc() ;                       /*  空白を読み飛ばす*/
  672.                   fileadr = (int)readi() ;        /* ファイルアトレス */
  673.                   putobject((char*)&fileadr,sizeof(fileadr));/* 書出  */
  674.                   filesize = (int)readi();        /* バッファサイズ   */
  675.                   putobject((char*)&filesize,sizeof(filesize));/* 書出*/
  676.                   putobject(filename,i+1) ;       /* ファイル名書出   */
  677.                   break ;
  678.  
  679.        case ';' :                       /* 注釈行を無視               */
  680.                   break ;
  681.        case 'L' : x=(int)readi();       /* label名を読む              */
  682.                   if(!eoln()) ch=readc() ;
  683.                   if(ch=='=') labelvalue=(int)readi();
  684.                                                    /* label値がある時 */
  685.                   else         labelvalue=pc;      /* ない時はpcの値  */
  686.                   update(x);                       /* label登録       */
  687.                   break ;
  688.        case ' ' : ch=readc();        /* 空白の時は その行をアセンブル */
  689.                   assemble(); 
  690.        default  : ;
  691.       }
  692.       readln() ;
  693.      }
  694. }
  695.  
  696. /*****************************************/
  697. /* assemblelist() : アセンブルリスト出力 */
  698. /*****************************************/
  699. static void assemblelist(void)
  700. {
  701.      reset(PcodeSourceName) ;   /* P-codeソースファイルのオープン       */
  702.  
  703.      printf("\n ADDR   OP   P      Q    P-code source statement\n");
  704.      printf(  "================================================\n");
  705.  
  706.      pc  = 0 ;
  707.  
  708.      for(;;) {
  709.       ch=readc();                       /* 行の最初の文字             */
  710.       switch(ch) {
  711.        case 'N' :
  712.        case 'F' :
  713.        case 'Q' :
  714.        case ';' :
  715.        case 'L' :  printf("                         %c",ch);
  716.            while(!eoln()) printf("%c",readc());
  717.            printf("\n");
  718.            readln();
  719.            if(ch=='Q') {
  720.             if(codesize != objsize)
  721.              printf(" %4d:\n   ~: constant data\n %4d:\n",
  722.                            codesize,objsize-1) ;
  723.                     fclose(pcsfile) ;   /* ソースファイルのクローズ   */
  724.             return;
  725.            }
  726.            break;
  727.  
  728.        case ' ' :  printf(" %4d: %3d %3d %6d",
  729.                pc, store[pc].vo.cdop, store[pc].vo.cdp , 
  730.                    store[pc].vo.cdq);
  731.            pc++;
  732.            printf("    %c",ch);
  733.            while(!eoln()) printf("%c",readc());
  734.            printf("\n");
  735.            readln();
  736.            break;
  737.       }
  738.      }
  739. }
  740.  
  741. /***************************************/
  742. /* main() : P-codeアセンブラメイン処理 */
  743. /***************************************/
  744. int main(int argc,char *argv[])
  745. {
  746.      codesize = atoi(argv[1]) ;         /* 命令コードの数             */
  747.      PcodeSourceName = argv[2] ;        /* P-codeソースファイル名     */
  748.      CompVersion     = argv[3] ;        /* コンパイラのバージョン     */
  749.      init();                            /* 各種初期設定               */
  750.      generate();                        /* アセンブル                 */
  751.      fclose(pcsfile)  ;                 /* ソースファイルのクローズ   */
  752.  
  753.      for(pc=0;pc<codesize;pc++) {       /* qオペランドの補正処理         */
  754.       op = store[pc].vo.cdop ;
  755.       if((/*lao*/ op == 5) || (/*ldox*/ op == 1 || (105<=op && op<=109) )
  756.                            || (/*srox*/ op == 3 || (75<=op && op<=79) ) )
  757.        store[pc].vo.cdq += objsize ;
  758.      }
  759.  
  760.      putobject((char*)&start,sizeof(start)) ; /* オブジェクト開始合図 */
  761.      putobject((char*)store,objsize*sizeof(_store)) ; /* オブジェクト出力*/
  762.      if(fflush(objfile) == EOF) paerr(3) ;
  763.      if(fclose(objfile) == EOF) paerr(3) ;
  764.                  /* クローズできなければ書き込み失敗の可能性がある    */
  765.  
  766.      fputs(         " *** Assemble completed. ***\n",stderr);
  767.      fprintf(stderr," *** code = %5d words  constant data = %5d words ***\n",
  768.                                 codesize,       objsize-codesize);
  769.  
  770.     if(argc==5) assemblelist();         /* アセンブルリストの出力     */
  771.  
  772.     return(0) ;                         /* 正常終了                   */
  773. }
  774.